home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / threads / ThreadsSharedMemBSD.c < prev    next >
C/C++ Source or Header  |  1990-12-05  |  12KB  |  466 lines

  1. /* begincopyright
  2.    Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.    Use and copying of this software and preparation of derivative works based
  4.    upon this software are permitted. Any distribution of this software or
  5.    derivative works must comply with all applicable United States export
  6.    control laws. This software is made available AS IS, and Xerox Corporation
  7.    makes no warranty about the software, its performance or its conformity to
  8.    any specification. Any person obtaining a copy of this software is requested
  9.    to send their name and post office or electronic mail address to:
  10.    PCR Coordinator
  11.    Xerox PARC
  12.    3333 Coyote Hill Rd.
  13.    Palo Alto, CA 94304
  14.    endcopyright */
  15.  
  16. /*
  17.  * ThreadsSharedMemBSD.c
  18.  *
  19.  * Demers, December 5, 1990 8:38:35 am PST
  20.  *
  21.  */
  22.  
  23.  
  24. #include "xr/BasicTypes.h"
  25. #include "xr/Threads.h"
  26. #include "xr/ThreadsBackdoor.h"
  27. #include "xr/ThreadsSharedMem.h"
  28. #include "xr/ThreadsSharedMemPrivate.h"
  29. #include "xr/ThreadsSharedMemBSDUtils.h"
  30. #include "xr/ThreadsMsgPrivate.h"
  31. #include "xr/Errno.h"
  32.  
  33. #include <sys/types.h>
  34. #include <sys/file.h>
  35. #include <sys/stat.h>
  36. #include <sys/mman.h>
  37.  
  38. #include <sys/param.h>    /* for dbtob() below */
  39.  
  40.  
  41. #define WARN_NOT_ISVTX        1
  42.  
  43. #define COUNT_FLUSHES 1
  44.  
  45.  
  46. #if WARN_NOT_ISVTX
  47.  
  48. #   define CHECK_NOT_ISVTX(test,fmt,x) \
  49.     { if( test ) XR_WarnNotISVTX((fmt), (x)); }
  50.  
  51. static void
  52. XR_WarnNotISVTX(fmt, x)
  53.     char *fmt;
  54.     int x;
  55. {
  56.     XR_ConsoleMsg("WARNING: backing file sticky bit not set.\n\t");
  57.     if( fmt ) {
  58.         XR_ConsoleMsg(fmt, x);
  59.         XR_ConsoleMsg("\n");
  60.     }
  61. }
  62.  
  63. #else
  64.  
  65. #   define CHECK_NOT_ISVTX(test,fmt,x)
  66.  
  67. #endif
  68.  
  69.  
  70.  
  71. extern void bcopy(/* char *from, char *to, int nbytes */);
  72.  
  73.  
  74. /*
  75.  * Directory and temp file name management ...
  76.  */
  77.  
  78.  
  79. #define LAST_DIRECTORY_TO_TRY    9
  80.  
  81.  
  82.  
  83. /*
  84.  * Initialization
  85.  */
  86.  
  87. static char *
  88. XR_SetShmTypeBSD(shmType)
  89.     char *shmType;
  90. {
  91.     (void)XR_SharedMemBSDSetSwapDir(DEFAULT_SWAP_DIR, DI_NONE);
  92.     return NIL;
  93. }
  94.  
  95.  
  96. static char *
  97. XR_SetShmArgBSD(shmArg)
  98.     char *shmArg;
  99. {
  100.     if( (shmArg == NIL) || (shmArg[0] != '/') ) {
  101.         return "BSD shared memory swap directory not full pathname";
  102.     }
  103.     if( XR_SharedMemBSDSetSwapDir(shmArg, DI_NONE) != 0 ) {
  104.         return "BSD shared memory swap directory bad (too long?)";
  105.     }
  106.     return NIL;
  107. }
  108.  
  109.  
  110. static char *
  111. XR_InitSharedMemBSD()
  112. {
  113.     int i, fd, ans;
  114.     char fnBuf[FILE_NAME_BUF_SIZE];
  115.  
  116.     (void)XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf), NIL, FI_NONE);
  117.     ans = access(fnBuf, (R_OK|X_OK) );
  118.     if( ans < 0 ) return("InitSharedMemBSD: can't access swap dir");
  119.     for( i = 0; ; i++ ) {
  120.         (void)XR_SharedMemBSDSetSwapDir(NIL, i);
  121.         ans = XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf),
  122.                 FN_LOCK, FI_NONE );
  123.     if( ans < 0 ) {
  124.         (void)XR_SharedMemBSDSetSwapDir(NIL, DI_NONE);
  125.         XR_Panic("InitSharedMemBSD: lock file name err");
  126.     }
  127.     fd = open(fnBuf, O_CREAT|O_EXCL, 0600);
  128.     if( fd >= 0 ) {
  129.         (void)close(fd);
  130.         return NIL;
  131.     }
  132.         if( i >= LAST_DIRECTORY_TO_TRY ) {
  133.             (void)XR_SharedMemBSDSetSwapDir(NIL, DI_NONE);
  134.         return("InitSharedMemBSD: can't find unlocked swap subdir");
  135.     }
  136.     }
  137. }
  138.  
  139. /*
  140.  * NOTE: the following had better be called while running on Unix stack,
  141.  *   with no dependency on data or bss after return.  This is delicate!
  142.  */
  143.  
  144. static void
  145. XR_CleanUpSharedMemBSD()
  146. {
  147.     int i, ans, lans, dirIndex;
  148.     char fnBuf[FILE_NAME_BUF_SIZE];
  149.     char lfnBuf[FILE_NAME_BUF_SIZE];
  150.  
  151.     (void)XR_SharedMemBSDGetSwapDir(NIL, 0, &dirIndex);
  152.     if( dirIndex == DI_NONE ) return;
  153.  
  154.     for( i = 0; i < XR_maxThreads; i++ ) {
  155.         ans = XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf), FN_STACK, i);
  156.         if( ans >= 0 ) (void)truncate(fnBuf, 0);
  157.     }
  158.     ans = XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf),
  159.             FN_HEAP, FI_NONE );
  160.     if( ans >= 0 ) (void)truncate(fnBuf, 0);
  161.     ans = XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf),
  162.             FN_DATA, FI_NONE );
  163.     lans = XR_SharedMemBSDMkFileName(lfnBuf, (sizeof lfnBuf),
  164.             FN_LOCK, FI_NONE );
  165.     if( ans >= 0 ) (void)truncate(fnBuf, 0);
  166.     if( lans >= 0 ) (void)unlink(lfnBuf);
  167. }
  168.  
  169.  
  170. /*
  171.  * Shared data + bss
  172.  */
  173.  
  174. static char *
  175. XR_ShareMemInitialBSD(p)
  176.     XR_Pointer p;
  177. {
  178.     int fd, ans, written;
  179.     unsigned bytes;
  180.     XR_Pointer mmapAns;
  181.     extern int end;
  182.  
  183.     if( !XR_PAGE_ALIGNED(p) )
  184.         XR_Panic("ShareMemInitialBSD 0: not page-aligned");
  185.     bytes = XR_RoundToPage(
  186.             ((unsigned)(&end)) - ((unsigned)(p)),
  187.             XR_ROUND_UP );
  188.  
  189.     /* create temporary file */
  190.         ans = XR_SharedMemBSDGetBackingFile( FN_DATA, FI_NONE,
  191.                 SETLEN_NOCHANGE, &fd );
  192.         if( ans < 0 ) {
  193.             return("ShareMemInitialBSD: can't create backing file");
  194.         }
  195.         CHECK_NOT_ISVTX((ans>0), FN_DATA, 0);
  196.             
  197.     /* copy stuff into file */
  198.         written = 0;
  199.         while( written < bytes ) {
  200.             ans = write(fd, p+written, bytes-written);
  201.             if( ans <= 0 ) {
  202.                 return("ShareMemInitialBSD: write error");
  203.             }
  204.             written += ans;
  205.         }
  206.         ans = ftruncate(fd, written);
  207.         if( ans < 0 ) {
  208.             return("ShareMemInitialBSD2: ftruncate error");
  209.         }
  210.  
  211.     /* mmap the file */
  212.         mmapAns = (XR_Pointer)mmap(
  213.                 p,
  214.                 bytes, 
  215.                 PROT_READ|PROT_WRITE|PROT_EXEC,
  216.                 MAP_SHARED|MAP_FIXED,
  217.                 fd,
  218.                 0 );
  219.         if( mmapAns != p ) {
  220.             return("ShareMemInitialBSD: mmap error");
  221.         }
  222.     /* close the file */
  223.         (void)close(fd);
  224.  
  225.     return NIL;
  226. }
  227.  
  228.  
  229. /*
  230.  * "system memory"
  231.  */
  232.  
  233. static char *
  234. XR_InitSharedSysMemBSD(nBytes)
  235.     unsigned nBytes;
  236. {
  237.     XR_Pointer a, mmapAns;
  238.     int fd, ans;
  239.     unsigned sysMemBytes = XR_RoundToPage(nBytes, XR_ROUND_UP);
  240.  
  241.     a = XR_VMReserve(sysMemBytes);
  242.     XR_memInfo->mi_sysMemStart = a;
  243.     XR_memInfo->mi_sysMemFree = a;
  244.     XR_memInfo->mi_sysMemLimit = a + sysMemBytes;
  245.  
  246.     ans = XR_SharedMemBSDGetBackingFile(FN_HEAP, FI_NONE,
  247.             XR_memInfo->mi_sysMemLimit, &fd);
  248.     if( ans < 0 ) {
  249.         return("InitSharedSysMemBSD: can't create backing file");
  250.     }
  251.     CHECK_NOT_ISVTX((ans>0), FN_HEAP, 0);
  252.     mmapAns = (XR_Pointer)mmap(
  253.             a,
  254.             sysMemBytes, 
  255.             PROT_READ|PROT_WRITE|PROT_EXEC,
  256.             MAP_SHARED|MAP_FIXED,
  257.             fd,
  258.             a );
  259.     if( mmapAns != a ) {
  260.         return("InitSharedSysMemBSD: mmap error");
  261.     }
  262.     (void)close(fd);
  263.     return NIL;
  264. }
  265.  
  266.  
  267. #define XR_AllocSharedSysMemBSD    NIL
  268.  
  269.  
  270. /*
  271.  * Stacks
  272.  */
  273.  
  274.  
  275. static char *
  276. XR_InitSharedStackMemBSD(maxStacks, totalBytes)
  277.     unsigned maxStacks;
  278.     unsigned totalBytes;
  279. {
  280.     unsigned bytesToAllocate;
  281.     XR_Pointer a;
  282.  
  283.     bytesToAllocate = XR_RoundToPage(
  284.             totalBytes+(2*maxStacks*XR_GetPageSize()),
  285.             XR_ROUND_UP );
  286.     a = XR_VMReserve(bytesToAllocate);
  287.     XR_memInfo->mi_maxStacks = maxStacks;
  288.     XR_memInfo->mi_stacksStart = a;
  289.     XR_memInfo->mi_stacksFree = a;
  290.     XR_memInfo->mi_stacksLimit = a + bytesToAllocate;
  291.     return NIL;
  292. }
  293.  
  294.  
  295.  
  296. static XR_Pointer
  297. XR_AllocSharedStackMemBSD(index, nBytes)
  298.     int index;
  299.     unsigned nBytes;
  300. {
  301.     XR_Pointer protArea, newStk, newFree, mmapAns;
  302.     int fd, ans;
  303.  
  304.     if( (index < 0) || (index >= XR_memInfo->mi_maxStacks) ) {
  305.         XR_Panic("AllocSharedStackMemBSD 0: too many stacks");
  306.     }
  307.     protArea = XR_ComputeAddress(XR_memInfo->mi_stacksFree, 0, XR_ROUND_UP);
  308.     newStk = XR_ComputeAddress(protArea, 1, XR_ROUND_UP);
  309.     nBytes = XR_RoundToPage(nBytes, XR_ROUND_UP);
  310.     newFree = XR_ComputeAddress(newStk, nBytes, XR_DONT_ROUND);
  311.     if( newFree > XR_memInfo->mi_stacksLimit ) {
  312.         XR_Panic("AllocSharedStackMemBSD 1: too many bytes");
  313.     }
  314.     ans = XR_SharedMemBSDGetBackingFile(
  315.             FN_STACK, index, nBytes, &fd );
  316.     if( ans < 0 ) {
  317.         XR_Panic("AllocSharedStackMemBSD 2: can't create backing file");
  318.     }
  319.     CHECK_NOT_ISVTX((ans>0), "stack file %d", index);
  320.     mmapAns = (XR_Pointer)mmap(
  321.             newStk,
  322.             nBytes, 
  323.             PROT_READ|PROT_WRITE|PROT_EXEC,
  324.             MAP_SHARED|MAP_FIXED,
  325.             fd,
  326.             0 );
  327.     if( mmapAns != newStk ) {
  328.         XR_Panic("AllocSharedStackMemBSD 3: mmap error");
  329.     }
  330.     (void)close(fd);
  331.     XR_memInfo->mi_stacksFree = newFree;
  332.     return newStk;
  333. }
  334.  
  335. #if COUNT_FLUSHES
  336.  
  337. static int XR_sharedMemBSDFlushIndex;
  338. static int XR_sharedMemBSDFlushResult;
  339.  
  340. int XR_GetSharedMemBSDFlushIndex() { return XR_sharedMemBSDFlushIndex; }
  341. int XR_GetSharedMemBSDFlushResult() { return XR_sharedMemBSDFlushResult; }
  342.  
  343. #endif
  344.  
  345. static int
  346. XR_FlushSharedStackMemBSD(index, pLow, pHigh, minBytesToFlush, pBytesFlushed)
  347.     int index;
  348.     XR_Pointer pLow;
  349.     XR_Pointer pHigh;
  350.     int minBytesToFlush;
  351.     int *pBytesFlushed;
  352. {
  353.     int nBytes, nBytesAllocated;
  354.     int ans;
  355.     char fnBuf[FILE_NAME_BUF_SIZE];
  356.     struct stat statBuf;
  357.  
  358.     if( (index < 0) || (index >= XR_memInfo->mi_maxStacks) ) return (-EINVAL);
  359.  
  360.     nBytes = ((char *)(pHigh)) - ((char *)(pLow));
  361.     if( nBytes < 0 ) return (-EINVAL);
  362.  
  363.     ans = XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf), FN_STACK, index);
  364.     if( ans < 0 ) return (-ENAMETOOLONG);
  365.     
  366.     ans = stat(fnBuf, &statBuf);
  367.     if( ans < 0 ) return (-XR_GetErrno());
  368.  
  369.     nBytesAllocated = dbtob(statBuf.st_blocks);
  370.  
  371. #   if COUNT_FLUSHES
  372.         XR_sharedMemBSDFlushIndex = index;
  373. #   endif
  374.     if( (nBytes > 0)
  375.             || (nBytesAllocated < minBytesToFlush) ) {
  376.         if( pBytesFlushed != NIL ) *pBytesFlushed = 0;
  377. #       if COUNT_FLUSHES
  378.             XR_sharedMemBSDFlushResult = nBytesAllocated;
  379. #       endif
  380.         return (nBytesAllocated);
  381.     }
  382.     (void)truncate( fnBuf, 0 );
  383.     (void)truncate( fnBuf, statBuf.st_size );
  384.     if( pBytesFlushed != NIL ) *pBytesFlushed = nBytesAllocated;
  385. #   if COUNT_FLUSHES
  386.         XR_sharedMemBSDFlushResult = 0;
  387. #   endif
  388.     return (0);
  389. }
  390.  
  391.  
  392. /*
  393.  * Heap
  394.  */
  395.  
  396. static XR_Pointer
  397. XR_InitSharedHeapMemBSD(nBytes)
  398.     unsigned nBytes;
  399. {
  400.     XR_Pointer heapAddr, mmapAns;
  401.     int fd, ans;
  402.  
  403.     heapAddr = XR_VMReserve(nBytes);
  404.     XR_memInfo->mi_heapStart = XR_memInfo->mi_heapFree = heapAddr;
  405.     XR_memInfo->mi_heapLimit = XR_VMReserve(0);
  406.  
  407.     ans = XR_SharedMemBSDGetBackingFile(FN_HEAP, FI_NONE, heapAddr, &fd);
  408.     if( ans < 0 ) return NIL;
  409.     CHECK_NOT_ISVTX((ans>0), FN_HEAP, 0);
  410.     mmapAns = (XR_Pointer)mmap(
  411.             heapAddr,
  412.             nBytes, 
  413.             PROT_READ|PROT_WRITE|PROT_EXEC,
  414.             MAP_SHARED|MAP_FIXED,
  415.             fd,
  416.             heapAddr );
  417.     if( mmapAns != heapAddr ) return NIL;
  418.     (void)close(fd);
  419.     return heapAddr;
  420. }
  421.  
  422.  
  423. static int
  424. XR_MapSharedHeapSegBSD(seg)
  425.     XR_Seg seg;
  426. {
  427.     XR_Pointer newFree;
  428.     int ans;
  429.     char fnBuf[FILE_NAME_BUF_SIZE];
  430.  
  431.     ans = XR_SharedMemBSDMkFileName(fnBuf, (sizeof fnBuf), FN_HEAP, FI_NONE);
  432.     if( ans < 0 ) return ans;
  433.  
  434.     newFree = XR_ComputeAddress(seg->seg_addr, seg->seg_bytes, XR_DONT_ROUND);
  435.     ans = truncate(fnBuf, newFree);
  436.     if( ans < 0 ) return (-XR_GetErrno());
  437.  
  438.     return 0;
  439. }
  440.  
  441.  
  442.  
  443. #define XR_ApplyToSysMemBSD    NIL
  444.  
  445.  
  446.  
  447. struct XR_ShmImplRep XR_shmImplRepBSD = {
  448.     /* shmType */        "bsd",
  449.     /* data */            NIL,
  450.     /* setShmType */        XR_SetShmTypeBSD,
  451.     /* setShmArg */        XR_SetShmArgBSD,
  452.     /* initSharedMem */        XR_InitSharedMemBSD,
  453.     /* cleanUpSharedMem */    XR_CleanUpSharedMemBSD,
  454.     /* shareMemInitial */    XR_ShareMemInitialBSD,
  455.     /* initSharedSysMem */    XR_InitSharedSysMemBSD,
  456.     /* allocSharedSysMem */    XR_AllocSharedSysMemBSD,
  457.     /* initSharedStackMem */    XR_InitSharedStackMemBSD,
  458.     /* allocSharedStackMem */    XR_AllocSharedStackMemBSD,
  459.     /* flushSharedStackMem */    XR_FlushSharedStackMemBSD,
  460.     /* initSharedHeapMem */    XR_InitSharedHeapMemBSD,
  461.     /* mapSharedHeapSeg */    XR_MapSharedHeapSegBSD,
  462.     /* applyToSysMem */        XR_ApplyToSysMemBSD
  463. };
  464.  
  465.  
  466.